Repo auto make wiki page - ☆Wiki Sandbox - НТЦ 'Комплексные Системы'

D8-SqlClient

Сервис, предназначенный для импорта данных из внешних СУБД в систему Дельта с использованием SQL-запросов и экспорта данных из системы Дельта в таблицы СУБД.

Аргументы командной строки

  • -regserver (-r, -service)
    Регистрация службы.
  • -unregserver (-u)
    Отмена регистрации службы.
  • -run
    Запуск в режиме приложения (а не службы Windows NT).
  • -logsql
    Логирование всех отправляемых SQL-запросов.

Формат конфигурационного файла

<configuration logSql="true/false, default: false">
  <instances>
    <instance
      name="text" 
      traceLevel="trace_level"    [ Off ]
      destDbConstr="text, generalize constr" 
      destOverwrite="true/false, default: false" 
      clientllConstr="text" 
      clientllAuthConstr="text" 
      sourceProviderClass="oledb/odbc/mssql/oracle" 
      sourceConstr="text" 
      sourceSecondaryConstr="text" 
      failoverOnRequestError="true/false", default: true
      watchdogTimeout="timespan, default: 00:00:00 - not used" 
      impersonationUser="[domain\]username, default - not used" 
      impersonationPassword="userpassword, default - empty" 
      >
      <netuse
        remoteName="share_path" 
        localName="network_drive_name" 
        user="user" 
        password="password" />        
      <prepareLastTimeQuery>sql_query_template</prepareLastTimeQuery>
      <loadLastTimeQuery>sql_query_template</loadLastTimeQuery>
      <saveLastTimeQuery>sql_query_template</saveLastTimeQuery>
      <requests>
        <request
          name="text" 
          traceLevel="trace_level"    [ <instance>.traceLevel ]
          readRate="timespan, default: 00:01:00" 
          readSchedule="Schedule, default: *" 
          readImmediate="true/false, default: false" 
          syncRate="timespan, default: 00:30:00" 
          syncInterval="timespan, default: 01:00:00" 
          syncSchedule="Schedule, default: *" 
          syncImmediate="true/false, default: false" 
          singleRequest="true/false, default: false" 
          ignoreResult="true/false, default: false" 
          sourceTimeshift="timespan, default: 00:00:00" 
          disableResTimestampCheck="true/false", default: false
          useTransactions="true/false", default: false
          commandTimeout="int_seconds, default: null" >
          <copyFile
            sourcePath="file_path" 
            destPath="file_path" 
            checkForModifications="true/false", default: false />
          <readSourceQuery formatCulture="culture, default: en-US">sql_query_template</readSourceQuery>
          <syncSourceQuery formatCulture="culture, default: en-US">sql_query_template</syncSourceQuery>
          <beforeWriteDestQuery formatCulture="culture, default: en-US">sql_query_template</beforeWriteDestQuery>
          <writeDestQuery formatCulture="culture, default: en-US">sql_query_template</writeDestQuery>
          <afterWriteDestQuery formatCulture="culture, default: en-US">sql_query_template</afterWriteDestQuery>
          <sourceTimezone
            timezoneString="timezone_definition, default: null" 
            bias="int_minutes, default: 0 [DEPRECATED]" 
            daylightSaving="true/false, default: false [DEPRECATED]" />
          <params>
            <param
              d8Id="int" 
              d8Type="Analog/Discrete/Vector/Record/Null" 
              d8MetaType="metaTypeShortName, default: null" 
              srcId1="text" 
              srcId2="text" 
              coefK="double, default: 1.0" 
              coefC="double, default: 0.0" 
              readToClientll="int, default: 1" 
              syncToClientll="int, default: 0" />
            <param ... />
            ...
          </params>
        </request>
        <request ... />
        ...
      </requests>
    </instance>
    <instance ... />
    ...
  </instances>
</configuration>

Тэг <configuration>

Корневой тэг. Его элементы:

  • logSql
    Признак логирования всех отправляемых SQL-запросов.
  • @<instances>@
    Содержит перечень тэгов <instance> с описанием инстансов Дельта.

Тэг <instance>

Содержит описание одного инстанса Дельта. Его атрибуты и вложенные тэги:

  • name
    Логическое имя инстанса. Используентся для логирования.
  • traceLevel
    Уровень трассировки. Определяет то, насколько подробным будет вывод в файл трассировки применительно к событиям этого инстанса.
    Возможные значения: Off, Critical, Error, Warning, Information, Verbose, Verbose2, Verbose3, Verbose4, All.
    При уровне Verbose в журнал трассировки выводится текст SQL-запросов, если не используется настройка logSql.
  • destDbConstr
  • archiveDbConstr
    Строка подключения к архивной БД Дельта. Можно не указывать, если запись данных в архив не требуется.
  • archiveOverwrite
  • destOverwrite
    Разрешение на перезапись данных в архиве Дельта.
  • clientllConstr
    Строка подключения к датасерверу Дельта. Не нужно указывать, если запись данных в датасервер не требуется.
  • clientllAuthConstr
    Строка подключения к БД НСИ Дельта, которая будет использоваться для Windows-авторизации в датасервере.
  • sourceProviderClass
    Тип подключения к БД-источнику. Возможные значения:
    • odbc - ODBC (System.Data.Odbc.OdbcConnection)
    • oledb - OLEDB (System.Data.OleDb.OleDbConnection)
    • oracle - Oracle (System.Data.OracleClient.OracleConnection)
    • mssql - MS SQL Server (System.Data.SqlClient.SqlConnection)
  • sourceSecondaryConstr
    Строка подключения к вторичному (резервному) БД-источнику. Если строка подключения вторичного источника указана, то в случае ошибки в работе с первичным источником служба переключится на вторичный источник. При возникновении первой ошибки с вторичным источником служба переключится обратно на первичный источник.
  • failoverOnRequestError
    Признак того, считать ли ошибки выполнения SQL-запросов поводом для переключения на резервный источник данных. Если нет, то поводом будут только ошибки подключения к источнику.
     
  • watchdogTimeout
    Если указано - период времени, с которым будет срабатывать сторожевой таймер в потоке, обрабатывающем инстанс, если поток перестанет отвечать на запросы.
  • impersonationUser
    Если указано - задает учетную запись, от лица которой будет выполнятся поток.
  • impersonationPassword
    Задает пароль для учетной записи impersonationUser.
  • <netuse>
    Описывает сетевой ресурс, который нужно подключить перед выполнением запросов (см. ниже).
  • <prepareLastTimeQuery>
    Текст SQL-запроса для для подготовки хранилища состояния обработки данных.
    Может использоваться для того, чтобы создать таблицы, необходимые службе для сохранения меток времени последних принятых данных или выполнения любых других подготовительных действий. Этот запрос выполняется в первую очередь. Запрос не выполняется, если тэг <prepareLastTimeQuery> не указан.
     
  • <loadLastTimeQuery>
    Текст SQL-запроса, который используется для считывания последних меток времени параметров на старте службы. Этот запрос выполняется после запроса <prepareLastTimeQuery>. Загрузка последних меток времени не выполняется, если тэг <loadLastTimeQuery> не указан.
  • <saveLastTimeQuery>
    Текст SQL-запроса, который используется для сохранения последних меток времени параметров после выполнения очередного считывания данных. Запрос не выполняется, если тэг <saveLastTimeQuery> не указан.
  • <requests>
    Содержит список тэгов <request> с описанием запросов на чтение и синхронизацию данных.

Тэг <netuse>

Описывает сетевой ресурс, который нужно подключить перед выполнением запросов. Его атрибуты:

  • remoteName
    Сетевой путь общей папки.
  • localName
    Имя локального сетевого диска (можно не указывать).
  • user
    Имя пользователя для доступа к сетевому ресурсу (можно не указывать).
  • password
    Пароль для доступа к сетевому ресурсу (можно не указывать).

Тэг <request>

Описывает один запрос на чтение и, опционально, синхронизацию (перечитывание) данных.

  • name
    Логическое имя запроса. Используентся для логирования.
  • traceLevel
    Уровень трассировки. Определяет то, насколько подробным будет вывод в файл трассировки применительно к событиям этого запроса.
    При уровне Verbose в журнал трассировки выводится текст SQL-запросов, если не используется настройка logSql.
  • readRate
    Периодичность выполнения запроса на чтение данных.
  • readSchedule
    Расписание выполнения запроса на чтение данных. Если оно задано, запрос readSourceQuery будет выполнятся по заданному расписанию, но не чаще, чем с периодом, заданным в readRate.
  • readImmediate
    Признак того, нужно ли выполнить чтение сразу при запуске службы.
    Если он readImmediate="true", то первый раз запрос readSourceQuery будет выполнен сразу на старте службы, невзирая на расписание. Далее запросы будут выполнятся по расписанию.
  • syncRate
    Периодичность выполнения запроса на синхронизацию данных. Если равна нулю (request.syncRate="00:00:00"), то синхронизация не выполняется.
  • syncInterval
    Глубина синхронизации по времени.
  • syncSchedule
    Расписание выполнения запроса на синхронизацию данных.
  • syncImmediate
    Признак того, нужно ли выполнить синхронизацию сразу при запуске службы.
  • singleRequest
    Если установлено значение true, то все параметры обрабатываются одним запросом. Если часть параметров при этом не удалось обработать, то повторных запросов не происходит.
  • ignoreResult
    Если установлено в true, то результаты выполнения SQL-запроса игнорируются. Такой запрос не может использоваться для получения данных.
  • <copyFile>
    Если этот элемент указан, то он описывает какой файл и куда нужно копировать каждый раз перед выполнением запросов readSourceQuery и syncSourceQuery.
    Опционально можно задать проверку на наличие изменений в файле.
  • <readSourceQuery>
    Текст SQL-запроса, который используется для чтения данных из БД-источника.
  • <syncSourceQuery>
    Текст SQL-запроса, который используется для синхронизации данных из БД-источника. Если не указан, то считается что текст запроса синхронизации такой же, что и текст запроса на чтение данных.
  • <beforeWriteDestQuery>
    Текст SQL-запроса, который выполняется в БД-получателе перед выполнением запроса writeDestQuery. Можно не указывать. Выполняется только при наличии запроса writeDestQuery.
  • <writeDestQuery>
    Текст SQL-запроса, который выполняется в БД-получателе для сохранения данных. Если указан запрос beforeWriteDestQuery, то запрос writeDestQuery выполняется только при успешном выполнении запроса beforeWriteDestQuery. Если указан writeDestQuery, то стандартный механизм сохранения данных в архиве и датасервере не используется.
  • <afterWriteDestQuery>
    Текст SQL-запроса, который выполняется в БД-получателе после успешного выполнения запроса writeDestQuery. Можно не указывать. Выполняется только при наличии запроса writeDestQuery.
  • <sourceTimezone>
    Задает часовой пояс меток времени в БД-источнике.
  • sourceTimeshift
    Задает дополнительный сдвиг времени к меткам времени, получаемым от БД-источника.
  • disableResTimestampCheck
    Позволяет выключить проверку на то, что значения параметра принимаются с увеличивающимися метками времени.
  • useTransactions
    Включает использование транзакций для запросов beforeWriteDestQuery, writeDestQuery, afterWriteDestQuery.
    Все эти запросы будут выполняться в одной транзакции. В случае ошибки транзакция откатывается.
  • commandTimeout
    Таймаут выполнения SQL-запроса (в секундах). Если не указано или ноль, то используется значение по умолчанию, установленное провайдером БД.
  • <params>
    Содержит перечень тэгов <param>, описывающих связь данных в БД-источнике и инстансе Дельта.

Тэг <sourceTimezone>

Содержит описание временной зоны. Имеет единственный атрибут:

  • timezoneString
    Строка определения временной зоны в формате TimeConverter.

Устаревшие атрибуты (использовались вместо timezoneString):

  • bias
    Сдвиг в минутах от UTC.
  • daylightSaving
    Признак использования переходов на летнее/зимнее время.

Тэг <param>

Задает сопоставление между идентификаторами, применимыми к БД-источнику и идентификаторами параметров Дельта.

  • d8Id
    Идентификатор параметра Дельта.
  • d8Type
    Тип параметра Дельта.
    Если d8Type="Null", то значения, получаемые в результате выполнения запросов чтения данных не конвертируются в типы данных Дельта, а сохраняются в виде массива объектов.
    Возможные типы параметров:
    • Analog - аналоговый
    • Discrete - дискретный
    • Vector - векторный
    • Record - табличный
    • Null - неопределенный
  • d8MetaType
    Мета-тип параметра (краткое имя типа).
  • srcId1
    Первый идентификатор данных в БД-источнике.
  • srcId2
    Второй идентификатор данных в БД-источнике. Можно не указывать, если одного идентификатора (srcId1) достаточно для связывания данных.
  • coefK
    Коэффициент, на который будут помножены получаемые значения.
  • coefC
    Коэффициент, который будет прибавлен к получаемым значениям.
  • readToClientll
    Ограничение по количеству значений из результата выполнения запроса readSourceQuery, отправляемых в датасервер.
    По умолчанию sendLimit="1" и отправляется только самое последнее значение. Если значение 0, то данные параметра вообще не отправляются в датасервер.
    Если указано значение n > 1, то отправляются n последних значений (с бóльшими метками времени) для этого параметра.
  • syncToClientll
    Ограничение по количеству значений из результата выполнения запроса syncSourceQuery, отправляемых в датасервер.
    По умолчанию 0 и данные параметра не отправляются в датасервер.
    Если указано значение n > 0, то отправляются n последних значений (с бóльшими метками времени) для этого параметра.

Тэг <copyFile>

Описывает процедуру копирования файла перед выполнение запросов чтения и синхронизации данных.

  • sourcePath
    Полный путь файла, который нужно копировать.
  • destPath
    Полный путь файла в папке назначения.
  • checkForModifications
    Если true, то размер файла и время его изменения будет предварительно сравнено со значениями, полученными при последнем копировании (с момента запуска службы). Если окажется, что файл не изменился, то запрос чтения/синхронизации не выполняется (и файл не копируется).

Токены для формирования SQL-запросов

Текст запросов readSourceQuery, syncSourceQuery, prepareLastTimeQuery, loadLastTimeQuery, saveLastTimeQuery может содержать токены, заменяемые на значения, которые зависят от контекста выполнения запроса (идентификаторы параметров, последнее время параметра, получаемые значения и метки времени, текущее время и т.д.). Конкретный набор токенов для каждого запроса свой.
Токены можно разделить на две группы: токены для формирования текста SQL-запроса и токены для парсинга результата запроса. Токены для парсинга начинаются на #res.

Токены для формирования SQL-запроса

Общий формат токена:

    {#reqtoken} или {#reqtoken:foramt}
    {#reqtoken-paramname} или {#reqtoken-paramname:foramt}
    {#reqtoken-paramname?} или {#reqtoken-paramname?:foramt}
    {#reqtoken/subtokenIdx}
    {#reqtoken/subtokenName}
    {#reqtoken/subtokenName-paramname?:format}

Через слэш можно указать индекс (subtokenIdx) или наименование поля (subtokenName) внутри токена. Для значений-массивов (токен d8value) это будет индекс в массиве или название свойства в мета-типе.

Через минус можно указать имя параметра команды (paramname) на выполнение SQL-запроса. Если имя параметра команды указано, то значение будет передано в СУБД не в виде текста команды, а в виде параметра. Это можно использовать, чтобы передавать значения, которые сложно сериализовать в текст (например, дата/время или строки со спецсимволами).

Вопросительный знак после paramname означает, что значение может быть null.

Через двоеточие можно опционально указать форматирование в стиле .NET. Например:

    SELECT * FROM srctable WHERE srct > '{#lasttime:yyyy-MM-dd HH:mm:ss}'

При подстановке значения вместо токена будет использована культура, указанная в атрибуте formatCulture тэга с описанием запроса (<xxxQuery>).

Поддерживаемые токены (reqtoken):
  • d8id - param.d8Id
  • d8value - значение параметра системы Дельта с id равным param.d8Id
  • d8value/0 - значение с индексом 0 (первое) для значения-массива
  • d8value/1 - значение с индексом 1 для значения-массива
  • d8value/N - значение с индексом N для значения-массива
  • d8value/SomeProp - значение свойства с названием SomeProp
  • d8timestamp - метка времени параметра системы Дельта с id равным param.d8Id
  • d8state - статус параметра системы Дельта с id равным param.d8Id
  • d8xstate - доп.статус параметра системы Дельта с id равным param.d8Id
  • srcid1 - param.srcId1
  • srcid2 - param.srcId2
  • lasttime - последняя метка времени параметра системы Дельта с id равным param.d8Id. Для запроса saveLastTimeQuery эта метка времени передается в UTC. Для запроса readSourceQuery/syncSourceQuery это метка времени переводится в часовой пояс, указанный в тэге sourceTimezone.
  • localtime - текущее местное время
  • utctime - текущее время UTC

Токены для парсинга результатов SQL-запроса

Общий формат токена:

    {#restoken}
    {#restoken/subtokenIdx}
    {#restoken/subtokenName}
    {#restoken:format}
    {#restoken,subst}
    {#restoken,subst:format}
    {#restoken:?datatype}
    {#restoken:format?datatype}
    {#restoken?:format?datatype}
    {#restoken?:format?datatype}

Через слэш можно указать индекс (subtokenIdx) или название свойства (@subtokenName) для значений векторных или табличных парметров.

Через запятую можно указать текст (subst), на который токен будет заменен на этапе формирования текста SQL-запроса. Например:

    SELECT srcvalue AS {#resValue,VAL} FROM srctable

Через двоеточие можно указать формат (format), в котором источник данных возвращает значение. Например:

    SELECT srct AS {#resTimestamp,TM:ddMMyyyyHHmm} FROM srctable

Через знак вопроса можно указать тип данных, к которому нужно привести значение, которое источник данных возвращает. Например:

    SELECT {#resTimestamp:ddMMyyyyHHmm?System.DateTime}srct FROM srctable
    SELECT srcint{#resValue:?System.Int32} FROM srctable

Поддерживаемые токены (restoken):
  • ressrcid1 - param.srcId1
  • ressrcid2 - param.srcId2
  • resvalue - значение параметра
  • restimestamp - метка времени параметра. Будет переведена из часового пояса, указанного в тэге sourceTimezone, в UTC.
  • resstate - статус параметра
  • resxstate - доп.статус параметра
  • resignore - поле игнорируется

Во всех случаях регистр имен токенов (reqtoken) не имеет значения.

Вопросительный знак в конце названия токена означает nullable-тип данных. Значения таких типов данных конвертируются в null при чтении БД-источника, если в результате запроса вернулся DbNull. А при форматирование запроса для записи в БД-получатель такие значения форматируются в строку "NULL", а апострофы вокруг него удаляются (при их наличии).

Если нужно, чтобы данные передавались БД-провайдеру в виде параметров, а не текста, то нужно указать paramname.

Особенности обработки запросов

Запрос prepareLastTimeQuery

Можно не указывать.

Запрос используется для подготовки БД для хранения последних полученных меток времени. Для этого в БД должна быть создана таблица, где можно хранить ключ параметра и его последнюю метку времени или хранимые процедуры для чтения и записи последних меток времени.
Метка времени в БД должна быть типа DateTime. Ключом может быть целое число (d8Id) или строка (srcId1, srcId2 или их комбинация). Имя таблицы значения не имеет.
Токены форматирования не используются, результирующие данные запроса не анализируется.
Выполняется один раз на старте службы. Если запрос выполняется с ошибкой, то он будет выполнен повторно через некоторое время. Другие запросы не будут выполнятся, пока prepareLastTimeQuery не выполнится корректно.

Например:

    IF (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='lasttime') IS NULL
    BEGIN
        CREATE TABLE [dbo].[lasttime]([N] [int] NOT NULL, [T] [datetime] NOT NULL,
        CONSTRAINT [PK_lasttime] PRIMARY KEY ([N] ASC))
    END

Запрос loadLastTimeQuery

Можно не указывать (тогда последние метки времени не инициализируются).

Запрос используется для считывания последних меток времени параметров на старте службы.
Поддерживаются токены:
  • d8id
  • srcid1
  • srcid2

Результатом запроса всегда считается одно значение типа DateTime (в UTC).
Выполняется один раз на старте службы, но не раньше, чем выполнится prepareLastTimeQuery.

Например:

    SELECT T FROM [dbo].lasttime where N={#d8Id}

Запрос saveLastTimeQuery

Можно не указывать.

Запрос используется для сохранения последних меток времени параметров.
Поддерживаются токены форматирования:
  • d8id
  • srcid1
  • srcid2
  • lasttime - всегда передается в UTC

Результирующие данные запроса никак не анализируются. Выполняется каждый раз, когда служба получает значение с более свежей меткой времени по какому-то параметру.

Например:

    IF EXISTS (SELECT N FROM [dbo].lasttime where N={#d8Id})
    UPDATE [dbo].lasttime SET T='{#lastTime:yyyy-MM-dd HH:mm:ss}' WHERE N={#d8Id}
    ELSE
    INSERT INTO [dbo].lasttime (N, T) VALUES ({#d8Id}, '{#lastTime:yyyy-MM-dd HH:mm:ss}')

Запрос readSourceQuery

Запрос используется для считывания данных из БД-источника. Вызывается периодически для каждого тэга request. Сначала текст запроса формируется для первого param в тэге request. При разборе таблицы, которая будет получена как результат запроса, все парамтеры (тэги param), для которых в этой таблице будут найдены значения, помечаются как обработанные. Дальше запрос повторяется для всех param в тэге request, для которых флаг обработки еще не выставлен. Запрос повторяется до тех пор, пока список тэгов param не будет пройден до конца либо пока у всех тэгов param не будет выствлен флаг обработки. Если по ходу этого цикла формирования запросов будет сформирован запрос с текстом, таким же, как текст запроса, отправленного на предыдущем этапе цикла, то такой запрос не выполняется.

Кроме периодичности выполнения запроса (атрибут readRate), можно указать расписание readSchedule. Если оно задано, запрос readSourceQuery будет выполнятся по заданному расписанию, но не чаще, чем с периодом, заданным в readRate.
В дополнение к readSchedule можно указать атрибут readImmediate. Если он имеет значение true, то первый раз запрос readSourceQuery будет выполнен сразу на старте службы, невзирая на расписание. Далее запросы будут выполнятся по расписанию.

Поддерживаются токены:
  • utctime - всегда в UTC
  • localtime - всегда передается в часовом поясе sourceTimezone
  • d8id
  • srcid1
  • srcid2
  • lasttime - перед запросом переводится из UTC в часовой пояс sourceTimezone и вычитается значение sourceTimeshift
  • ressrcid1
  • ressrcid2
  • resvalue
  • restimestamp - будет переведена из часового пояса sourceTimezone в UTC и к ней будет прибавлено значение sourceTimeshift
  • resstate
  • resxstate
  • resignore

Для параметров Дельта с типом Vector (т.е. если <param>.d8Type="Vector") все значения в строке результатов запроса, помеченные токеном resvalue, записываются в один список объектов, который затем сериализуется в векторное значение, которе можно отправить датасерверу или записать в архив векторного параметра.

Для параметров Дельта с типом Record все значения в строке результатов запроса, помещаются в запись табличного параметра. Чтобы определить формат записи используется мета-тип (<param>.d8MetaType). Затем, при обработке запроса writeDestQuery можно обращаться к элементам этого списка с помощью токенов d8value/1 или d8value/SomeProp.

Для параметров Дельта с типом Null все значения в строке результатов запроса, помеченные токеном resvalue, записываются в один список объектов, который никак не сериализуется. Затем, при обработке запроса writeDestQuery можно обращаться к элементам этого списка с помощью токенов d8value/0, d8value/1, и т.д.

Для каждого параметра Дельта с id равным -1 (<param>.d8Id="-1") в результате выполнения readSourceQuery может быть получено произвольное количество значений. Для параметров с определенным id - только одно или ниодного.

Если список параметров запроса пуст, то он автоматически заполняется единственным параметром вида

    <param d8Id="-1" d8Type="Null"/>

Примеры:

    SELECT srcvalue AS {#resValue,VAL}, TM AS {#resTimestamp,TM:ddMMyyyyHHmm},
    SKIP AS {#resIgnore,IGNORE}, QUAL{#resState}, {#resxstate,AUX}
    FROM SRCTABLE WHERE IDENT='{#srcId1}' AND TM>'{#lasttime:yyyy-MM-dd HH:mm:ss}'

    -- групповая выборка
    SELECT *{#ressrcid1}{#resvalue}{#resignore}{#restimestamp}{#resignore}{#resstate}
    FROM SRCTABLE WHERE TM>='{#lasttime:yyyy-MM-dd}'

    -- выборка из архива системы Дельта за текущие сутки
    SELECT {#ressrcid1,N}, {#resvalue,V},
    CAST(CAST(CAST('{#utctime:yyyy-MM-dd}' as datetime) as float) + CAST(T as float)/(1000.*60.*60.*24.) as datetime),
    {#resstate,S}, {#resxtate,XS}
    FROM dbo.A{#utctime:ddMMyyyy} WHERE N={#srcid1} AND V>100

    -- выборка из БД РДГ значений ПБР за текущие сутки
    -- param.srcId1 - это id ГТП, param.srcId2 - это номер ПБР
    SELECT
    CONVERT(nvarchar, CAST(PBRValueDate-693596 as datetime), 104) + ' '
    + CAST(PBRValueTime/(1000*60*60) as nvarchar) + ':'
    + CAST(PBRValueTime/(1000*60)%60 as nvarchar) + ':'
    + CAST(PBRValueTime/1000%60 as nvarchar) + '.'
    + CAST(PBRValueTime%1000 as nvarchar)
    AS {#restimestamp,TS:dd.MM.yyyy H:m:s.f}, {#resvalue,PBRValue}
    FROM dbo.RDGPlanValues
    WHERE PBRID=(SELECT TOP(1) PBRID FROM dbo.RDGPlans
    WHERE GTPNumber={#srcId1} AND PBRNumber={#srcId2} AND
    PBRDate=CAST(CAST('{#utctime:yyyy-MM-dd}' as datetime) as float)+693596 ORDER BY PBRID DESC)
    AND ParamID=(SELECT PDGParamID FROM dbo.RDGGTPs WHERE GtpID={#srcId1})
    ORDER BY PBRValueDate, PBRValueTime

Запрос syncSourceQuery

Обрабатывается аналогично readSourceQuery, за исключением того, что
  • токен lasttime принимает значение, равное текущему времени в часовом поясе источника минус значение syncInterval,
  • запросы loadLastTimeQuery/saveLastTimeQuery не обрабатываются,
  • значения в датасервер не отправляются никогда (записываются только в архив).

Запрос beforeWriteDestQuery

Выполняется, если в конфигурации указан запрос writeDestQuery.
Выполняется после чтения данных один раз (а не по разу для каждого значения или параметра).
Токены форматирования не поддерживает.

Запрос writeDestQuery

Выполняется после чтения данных и, если в конфигурации указан запрос beforeWriteDestQuery, только после успешного завершения запроса beforeWriteDestQuery.

При обработке writeDestQuery для каждого значения, полученного в результате чтения данных будут формироваться SQL-запросы. Если очередной SQL-запрос совпадет с предыдущим, то его выполнение будет пропущено и обработка перейдет к следующему значению.

Поддерживаются токены форматирования:
  • utctime - всегда в UTC
  • localtime - всегда передается в часовом поясе sourceTimezone
  • d8id
  • srcid1
  • srcid2
  • lasttime - всегда в UTC
  • srcid1
  • srcid2
  • d8value
  • d8value0
  • ...
  • d8value29
  • d8timestamp - всегда в UTC
  • d8state
  • d8xstate

Для того, чтобы использовать токены d8value0..d8value29 для обращения к элементам значений-массивов (записей), полученных в результате чтения данных, нужно, чтобы тип параметра <param>.d8Type был равен Null.

Запрос afterWriteDestQuery

Выполняется, если в конфигурации указан запрос writeDestQuery.
Выполняется после запроса writeDestQuery, если выполнение запроса writeDestQuery завершилось без ошибок.
Токены форматирования не поддерживает.

История версий

  • 1.4.21.0618
    • Исправлена ошибка из-за которой не работали запросы, если не указана строка соединения БД-получателя, даже если в ней нет необходиности.
  • 1.4.21.0400
    • Служба переведена на формат PrimtiveService.
    • Добавлены настройки traceLevel для элементов instance и request.
  • 1.3.20.0220
    • Добавлен построитель запросов QueryBuilder, для возможности написания универсальных запросов, совместимых с различные типы баз данных.
  • 1.3.19.0709
    • Добавлена настройка failoverOnRequestError. По умолчанию выставлена в true - считать ошибки выполнения запросов выборки данных поводом для переключения на резервный источник.
  • 1.3.18.0506
    • Добавлена возможность копирования файла перед выполнение запросов чтения/синхронизации данных.
    • Соединение с БД-источником теперь устанавливается непосредственно перед выполнением запросов к БД.
       
  • 1.3.18.0406
    • Добавлена функция перключения на резервный исчник данных в случае сбоя в работе с основным источником данных.
    • Исправлена ошибка из-за которой период чтения после ошибки увеличивался до минимум 60 секунд.
  • 1.3.17.0214
    • Добавлена возможность отправки нескольких значений для каждого параметра в датасервер после запроса чтения данных (атрибут <param>.readToClientll).
    • Добавлена возможность отправки значений в датасервер после запроса синхронизации данных (атрибут <param>.syncToClientll).
    • Изменена логика обработки последних меток времени. Если возникает ошибка при обработке запроса чтения данных, последние метки времени откатываются к состоянию, которое было до запуска обработки. Обработка последних меток времени полностью развязана с отправкой данных в датасервер.
  • 1.3.17.0320
    • Исправлена ошибка, из-за которой статистика значений, отправленных запросами writeDestQuery, могла определиться неверно.
  • 1.3.16.1027
    • Исправлена ошибка деления ноль в момент логирования статистики.
  • 1.3.16.0803
    • Добавлена настройка ignoreResult для запросов. Если указана, то все, что вернула SQL-команда игнорируется.
  • 1.3.16.0520
    • Добавлен таймаут на выполнения SQL-запросов.
  • 1.3.16.0412
    • Улучшено логирование ошибок преобразования типов данных.
    • Исправлена ошибка, которая могла произойти при избыточном конвертировании DateTime в String и обратно в DateTime.
    • Добавлена возможность использовать параметры в SQL-запросах. Теперь можно в имени тэга через минус указать имя соответствующего параметра.
    • Добавлена возможность использования транзакции для beforeWriteDestQuery, writeDestQuery и afterWriteDestQuery.
    • Улучшена обработка исключений.
  • 1.3.16.0329
    • Изменения в API.
  • 1.3.15.1125
    • Добавлена установка свойства AppDescr для соединения с датасервером.
  • 1.3.15.1022
    • Добавлена возможность запуска потока обработки инстанса из-под указанной учетной записи (тэги impersonationUser и impersonationPassword).
    • Добавлена возможность указывать тип данных как nullable.
  • 1.3.15.1016
    • Теперь после неужачной попытки соединения с БД будет сделана пауза в 1 минуту.
  • 1.3.15.0924
    • Добавлена возможно чтения данных в виде произвольных записей.
    • Добавлена возможность записи данных в БД-получатель произвольными SQL-запросами.
    • Для использования записи произвольными SQL-запросами можно использовать тэги <beforeWriteDestQuery>, <writeDestQuery>, <afterWriteDestQuery>.
    • Атрибуты <instance>.archiveDbConstr и <instance>.archiveOverwrite переименованы в destDbConstr и destOverwrite. Старые названия оставлены как синонимы для обратной совместимости.
    • Добавлены токени форматирования #d8value, #d8value0, #d8value1, .. #d8value29, #d8state, #d8xstate, #d8timestamp.
  • 1.2.15.0924
    • Теперь служба раз в пять минут выводит в лог статистику по выполненным запросам.
    • Для подключения к архивной БД Дельта теперь использует провайдер .NET (раньше использовался OLEDB).
  • 1.2.15.0923
    • Добавлен сторожевой таймер инстансов (настройка <instance>.watchdogTimeout).
  • 1.2.15.0724
    • Улучшен парсинг значений для токенов #resstate и #resxstate.
  • 1.2.15.0623
    • Добавлена возможность подключения сетевого ресурса с помощью <instance>.<netuse>.
    • Теперь пишет лог в отдельный evt-файл.
  • 1.2.15.0326
    • Добавлена настройка <request>.disableResTimestampCheck.
  • 1.2.15.0326
    • Добавлена поддержка векторных параметров.
    • Добавлена поддержка нескольких токенов #resvalue в одном запросе. В этом случае значение будет сериализована как массив объектов (IList<object>).
    • Теперь для токена #resvalue вместо строки форматирования можно указать имя системного типа .NET. Если оно указано, то получаемое от источника значение будет сконвертировано в этот тип (например, SELECT {#resvalue:?System.Double}'123.456', {#resvalue:?System.String}123456 FROM table).
    • Добавлена поддержка атрибута <request>.sourceTimeshift.
  • 1.2.14.1125
    • Переведена на .NET4, теперь использует классы из d8_client3 взамен d8_nativeclient.
    • Используется новый класс для перевода часовых поясов.
    • Добавлена настройка <timezone>.timezoneString. Если указана, то представляет собой строку с описанием часового пояса.
    • Добавлена настройка <request>.sourceTimezone. Эта величина прибавляется к меткам времени, получаемым в результатах выполнения запросов readSourceQuery/syncSourceQuery.
  • 1.1.14.1125
    • Исправлена ошибка, проявлявшаяся, если не указать <sourceTimezone>.
    • Выполнение запроса saveLastTimeQuery отделено от отправки последних значений в датасервер.
    • Теперь можно не указывать saveLastTimeQuery, если нужно только отправлять принятые данные в датасервер.
  • 1.1.14.0414
    • Теперь при отсутствии подключения к CS-DataServer служба не выполняет запросы к источникам данных, а при длительном отсутствии подключения, экземпляр соединения пересоздается полностью.
  • 1.1.13.1225
    • Исправлена ошибка в обработке readImmediate и syncImmediate.
  • 1.1.13.1007
    • Добавлена настройка <request>.singleRequest. Если установлено значение true, то все параметры обрабатываются одним запросом. Если часть параметров при этом не удалось обработать, то повторных запросов не происходит.
  • 1.1.13.0417
    • Теперь SQL-команды при выводе в лог ограничиваются по длине в 2048 символов.
    • Служба переведена на новый набор общих библиотек.
  • 1.0.12.0113
    • Добавлены функции расписания для запросов readSourceQuery/syncSourceQuery.
  • 1.0.11.1019
    • Добавлена обработка ситуации, когда подключение к CS-DataServer невозможно из-за отсутствия соединения с БД, в которой хранятся ключи авторизации.
  • 1.0.11.1006
    • Добавлена поддержка дискретных парамтеров. У тэга <param> теперь есть атрибут d8Type.
  • 1.0.11.0928
    • Теперь текст запроса saveLastTimeQuery может быть пустым. Тогда он не выполняется, но последние значения для параметров все-равно отправляются в CS-DataServer.
  • 1.0.10.1122
    • Исправлена ошибка в обработке syncRate.
  • 1.0.10.1113
    • Добавлена отправка в CS-DataServer. Отсылает только последнее (по времени) значение по каждому параметру.
    • Добавлено ожидание подключения с DataServer. Если соединения нет больше трех минут - работает без CS-DataServer.
       
  • 1.0.10.1025
    • Бета. Не пишет в CS-DataServer.

Ссылки